package tools

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"math"
	"strconv"
	"strings"
)

// BytesEqual 比较两个字节切片是否相等
func BytesEqual(a, b []byte) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

// ByteContain 判断 data 是否包含 prefix
// 如果存在返回第一次匹配的索引值, 如果不存在返回 -1
func ByteContain(data []byte, prefix []byte) int {
	prefixLen := len(prefix)
	dataLen := len(data)
	if prefixLen > dataLen {
		return -2 // 前缀长度超过数据长度，不可能找到匹配项
	}
	for i := 0; i <= dataLen-prefixLen; i++ {
		if BytesEqual(data[i:i+prefixLen], prefix) {
			return i // 返回匹配的位置
		}
	}
	return -1 // 没有找到匹配的位置
}

// MatchSuffix 判断 suffix 是否能和 data 结尾衔接, 找到最长重叠部分的起始索引
func MatchSuffix(data []byte, suffix []byte) (index int, b bool) {
	b = false
	index = -1
	var len1 = len(data)
	var len2 = len(suffix)
	if len1 < len2 {
		return
	}

	for i := 1; i < len2; i++ {
		if BytesEqual(suffix[0:i], data[len1-i:]) {
			b = true
			index = len1 - i
		}
	}
	return
}

// ByteToBinaryString 将一个 byte 转换成8位的二进制字符串。
func ByteToBinaryString(b byte) string {
	binaryString := ""
	for i := 7; i >= 0; i-- { // 从最高位到最低位
		if (b & (1 << i)) != 0 {
			binaryString += "1"
		} else {
			binaryString += "0"
		}
	}
	return binaryString
}

// ByteToHexStr 将一个 byte 转换成十六进制字符串
func ByteToHexStr(b byte) string {
	return strings.ToUpper(fmt.Sprintf("%02x", b))
}

// ByteArrayToHexStr 字节数组转16进制字符串
func ByteArrayToHexStr(b []byte) string {
	str := ""
	for i := 0; i < len(b); i++ {
		twoDigitHexStr := fmt.Sprintf("%02x", b[i])
		str = str + twoDigitHexStr
	}
	return strings.ToUpper(str)
}

// HexToInt64 16进制字符串转10进制 todo
func HexToInt64(hexStr string) (int64, error) {
	decimal, err := strconv.ParseInt(hexStr, 16, 64)
	if err != nil {
		return 0, err
	}
	return decimal, nil
}

// Int64ToHexStr 整型转16进制字符串 todo
func Int64ToHexStr(n int64) string {
	return fmt.Sprintf("%X\n", n)
}

// HexStrToByteArray 16进制字符串转byte数组
func HexStrToByteArray(hexStr string) (byteArr []byte, err error) {
	byteArr, err = hex.DecodeString(hexStr)
	if err != nil {
		return
	}
	return
}

// BytesToUint32 byte数组转uint32
func BytesToUint32(data []byte, endian string) uint32 {
	if len(data) > 4 || len(data) == 0 {
		return 0
	}
	var value uint32
	reader := bytes.NewReader(data)
	if endian == "big" || endian == "" {
		_ = binary.Read(reader, binary.BigEndian, &value)
	} else {
		_ = binary.Read(reader, binary.LittleEndian, &value)
	}
	return value
}

// BytesToUint16 byte数组转uint16
func BytesToUint16(data []byte, endian string) uint16 {
	if len(data) != 2 {
		return 0
	}
	var value uint16
	reader := bytes.NewReader(data)
	if endian == "big" || endian == "" {
		_ = binary.Read(reader, binary.BigEndian, &value)
	} else {
		_ = binary.Read(reader, binary.LittleEndian, &value)
	}
	return value
}

// Uint32ToBytes uint32 转换为 [4]byte
func Uint32ToBytes(n uint32, endian string) [4]byte {
	var byteLen [4]byte
	if endian == "big" || endian == "" {
		// 使用 PutUint 方法将 uint 转换为字节切片，并指定大端字节序
		binary.BigEndian.PutUint32(byteLen[:], n)
	} else {
		binary.LittleEndian.PutUint32(byteLen[:], n)
	}
	return byteLen
}

// Uint16ToBytes uint16 转换为 [2]byte
func Uint16ToBytes(n uint16, endian string) [2]byte {
	var byteLen [2]byte
	if endian == "big" || endian == "" {
		// 使用 PutUint 方法将 uint 转换为字节切片，并指定大端字节序
		binary.BigEndian.PutUint16(byteLen[:], n)
	} else {
		binary.LittleEndian.PutUint16(byteLen[:], n)
	}
	return byteLen
}

// ByteToFloat32 []byte 转换为 float32
func ByteToFloat32(data []byte, endian string) float32 {
	if len(data) != 4 {
		return 0
	}
	if endian == "big" {
		return math.Float32frombits(binary.BigEndian.Uint32(data))
	} else {
		return math.Float32frombits(binary.LittleEndian.Uint32(data))
	}
}
